Systems ManagerのRunCommandでSSHを使わずにShellライクにコマンドを実行する
おはようございます。加藤です。
今日はSystems Managerを使ってEC2の中身をSSHせずに管理する方法を紹介します。
SSHレスによるメリットは以下のようなものがあります。
- 公開鍵・秘密鍵を管理しなくてよい
ネットワークが繋がっていなくてもインバウンドを許可していなくても操作できる
EC2→SSM APIへのアウトバウンド通信が必要です。よって、インターネットへのアウトバウンドを開放する必要があります。 AWS Systems Manager のセットアップ | Systems Manager の前提条件 アウトバウンドをさらに絞りたい場合は、PrivateLinkを使用します。 PrivateLinkがリリースし新たにEC2, Systems Manager, ELB, Kinesis, Service CatalogがVPCエンドポイントに対応しました
私はTerraformでAWSを触ることが多いので、抜粋ですがTerraformのコードも記載しておきます。
環境・前提
項目 | バージョン |
---|---|
MacOS | 10.13.3(17D102) |
Go | 1.9.3 |
ssm-sh | v0.3.0 |
- VPCの基本的な操作
- EC2の基本的な操作
- AWS CLIの実行環境
- Credentials情報を配置済み
- Go言語の実行環境 > 急いで学ぶGo lang#1 概要とセットアップ
手順
EC2にアタッチするロールを作成
- IAM管理画面に切り替え
- ロールメニューを選択
- ロール作成
- ロールを使用するサービスに"EC2"を選択
- "AmazonEC2RoleforSSM"をアタッチ
- 任意のロール名を指定する(ここでは"AmazonEC2RoleforSSM"とした)
resource "aws_iam_instance_profile" "ec2role_for_ssm" { name = "ec2role_for_ssm" role = "${aws_iam_role.ec2role_for_ssm.name}" } resource "aws_iam_role" "ec2role_for_ssm" { name = "EC2RoleforSSM" path = "/" assume_role_policy = <<EOF { "Version": "2012-10-17", "Statement": [ { "Action": "sts:AssumeRole", "Principal": { "Service": "ec2.amazonaws.com" }, "Effect": "Allow", "Sid": "" } ] } EOF } resource "aws_iam_role_policy_attachment" "ec2role_for_ssm_attachment0" { role = "${aws_iam_role.ec2role_for_ssm.name}" policy_arn = "arn:aws:iam::aws:policy/service-role/AmazonEC2RoleforSSM" }
管理するEC2を作成
- EC2管理画面に切り替え
- セキュリティグループを作成
- インバウンド許可なし
- アウトバウンド全許可
- EC2を2台作成
- 作成したセキュリティグループを割り当て
- 作成したIAMロールを割り当て
セキュリティグループ
方向 | プロトコル | ポート範囲 | 送信元/先 |
---|---|---|---|
アウトバウンド | すべて | すべて | 0.0.0.0/0 |
アウトバウンド | すべて | すべて | ::/0 |
インスタンスパラメータ
インスタンス名 | タイプ | AMI_ID |
---|---|---|
amzn | t2.micro | ami-ceafcba8 |
amzn2 | t2.micro | ami-c2680fa4 |
## Outbound only ### security group resource "aws_security_group" "outbound_only" { name = "outbound_only" description = "outbound_only" vpc_id = "${aws_vpc.main.id}" tags { Name = "outbound_only" Project = "${var.project["name"]}" DeployBy = "Terraform" } } ### security group rule resource "aws_security_group_rule" "outbound_only_rule_egress0" { type = "egress" from_port = 0 to_port = 0 protocol = "-1" cidr_blocks = ["0.0.0.0/0"] ipv6_cidr_blocks = ["::/0"] security_group_id = "${aws_security_group.outbound_only.id}" }
resource "aws_instance" "amzn1" { ami = "ami-ceafcba8" instance_type = "t2.micro" subnet_id = "${aws_subnet.public0.id}" vpc_security_group_ids = ["${aws_security_group.outbound_only.id}"] key_name = "${aws_key_pair.main.key_name}" iam_instance_profile = "${aws_iam_instance_profile.ec2role_for_ssm.name}" tags { Name = "amzn1" Project = "${var.project["name"]}" DeployBy = "Terraform" } } resource "aws_instance" "amzn2" { ami = "ami-c2680fa4" instance_type = "t2.micro" subnet_id = "${aws_subnet.public1.id}" vpc_security_group_ids = ["${aws_security_group.outbound_only.id}"] key_name = "${aws_key_pair.main.key_name}" iam_instance_profile = "${aws_iam_instance_profile.ec2role_for_ssm.name}" tags { Name = "amzn2" Project = "${var.project["name"]}" DeployBy = "Terraform" } }
マネジメントコンソール・AWS CLIから操作する
本記事では紹介しません、参考URLを記載しておきます。
ssm-shから操作する
ssm-shはGo言語で書かれたツールです。Systems Managerのsend commandsを利用しSSHせずにShellライクでコマンドを使えます。
バージョンが<=1、OSSなので、使用は自己責任でお願い致します。
インストール
go get -u github.com/itsdalmo/ssm-sh
ヘルプ確認
ヘルプを確認してみます。デフォルトリージョンがeu-west-1になっているので、日本リージョンを明示的に指定する必要があるようです。
ssm-sh --help Usage: ssm-sh [OPTIONS] <list | run | shell> Application Options: -v, --version Print the version and exit. AWS Options: -p, --profile= AWS Profile to use. (If you are not using Vaulted). -r, --region= Region to target. (default: eu-west-1) Help Options: -h, --help Show this help message Available commands: list List managed instances. (aliases: ls) run Run a command on the targeted instances. shell Start an interactive shell. (aliases: sh)
インスタンス一覧取得
listコマンドを使って管理できるインスタンス一覧を取得します。
ssm-sh -r ap-northeast-1 list
Instance ID | Name | State | Image ID | Platform | Version | IP | Status | Last pinged i-055d87cb9xxxxxxxx | amzn2 | running | ami-c2680fa4 | Amazon Linux | 2.0 | 10.0.1.195 | Online | 2018-03-06 09:12 i-0219de9d6xxxxxxxx | amzn1 | running | ami-ceafcba8 | Amazon Linux AMI | 2017.09 | 10.0.0.230 | Online | 2018-03-06 09:12
意図した通りの情報を取得できています。
ワンライナー実行
ワンライナーという言い方は適切でないかもしれません...
コマンド実行が完了後にすぐに操作端末のShellに戻ってくるモードです。
試しにコマンドを実行してみます。
ssh-sh -r (リージョン) run -t (インスタンスID) (コマンド)
### amzn ssm-sh -r ap-northeast-1 run -t i-0219de9d6xxxxxxxx cat /etc/os-release Initialized with targets: [i-0219de9d6xxxxxxxx] Use ctrl-c to abort the command early. i-0219de9d6xxxxxxxx - Success: NAME="Amazon Linux AMI" VERSION="2017.09" ID="amzn" ID_LIKE="rhel fedora" VERSION_ID="2017.09" PRETTY_NAME="Amazon Linux AMI 2017.09" ANSI_COLOR="0;33" CPE_NAME="cpe:/o:amazon:linux:2017.09:ga" HOME_URL="http://aws.amazon.com/amazon-linux-ami/" ### amzn2 ssm-sh -r ap-northeast-1 run -t i-055d87cb9xxxxxxxx cat /etc/os-release Initialized with targets: [i-055d87cb9xxxxxxxx] Use ctrl-c to abort the command early. i-055d87cb9xxxxxxxx - Success: NAME="Amazon Linux" VERSION="2.0 (2017.12)" ID="amzn" ID_LIKE="centos rhel fedora" VERSION_ID="2.0" PRETTY_NAME="Amazon Linux 2.0 (2017.12) LTS Release Candidate" ANSI_COLOR="0;33" CPE_NAME="cpe:2.3:o:amazon:amazon_linux:2.0" HOME_URL="https://amazonlinux.com/"
おお!ばっちり動作していますね
Shellライク
ここが本記事のメインです。実際に触ってみます。
ssh-sh -r (リージョン) shell -t (インスタンスID)
ssm-sh -r ap-northeast-1 shell -t i-055d87cb9xxxxxxxx Initialized with targets: [i-055d87cb9xxxxxxxx] Type 'exit' to exit. Use ctrl-c to abort running commands. » pwd i-055d87cb9xxxxxxxx - Success: /usr/bin » whoami i-055d87cb9xxxxxxxx - Success: root » ping -c 3 amazonaws.com i-055d87cb9xxxxxxxx - Success: PING amazonaws.com (72.21.206.80) 56(84) bytes of data. 64 bytes from 206-80.amazon.com (72.21.206.80): icmp_seq=1 ttl=223 time=187 ms 64 bytes from 206-80.amazon.com (72.21.206.80): icmp_seq=2 ttl=223 time=187 ms 64 bytes from 206-80.amazon.com (72.21.206.80): icmp_seq=3 ttl=223 time=188 ms --- amazonaws.com ping statistics --- 3 packets transmitted, 3 received, 0% packet loss, time 2000ms rtt min/avg/max/mdev = 187.578/187.785/188.156/0.565 ms » curl https://checkip.amazonaws.com i-055d87cb9xxxxxxxx - Success: 54.250.xxx.xxx » cd /root i-055d87cb9xxxxxxxx - Success: » pwd i-055d87cb9xxxxxxxx - Success: /usr/bin » exit
しっかりと動作しました!
cdでディレクトリ移動ができないのは想定どおりです、コマンド1つごとのSSMのRunShellScriptが走っていて連続性が無いためです。
なので以下のような操作も行えません。
- TUI
- yes/no など応答を求めるもの
Systems Managerを確認するとしっかりとコマンド履歴が残っていました。
あとがき
前回のブログでSSでの管理についても触れて欲しかったとコメントを頂いたのがきっかけでこの記事を書こうと思いました。
今回は扱いませんでしたが、エージェントを入れればオンプレミスにあるサーバもSSM管理下の置くことができます。
SSMは本当に便利ですね、もっと活用していこうと思います。
最初は自分でツールを作ろうとしましたが、社内で相談してみるとこのツールを教えてもらいブログにしました。